﻿using System;
using System.Net;
using System.Windows;

using System.Windows.Input;
using Topping.Core.Logic;
using TopMachine.Topping.Dto;
using TopMachine.Topping.Common.Structures;
using TopMachine.Topping.Engine.GameController;
using Topping.Core.Proxy.Local.Client;
using Topping.Core.Logic;
using Topping.Core.Logic.Client;
using System.Collections.Generic;
using TopMachine.Desktop.Overall;


namespace Topping.Core.Proxy.Local
{
    public class GameState : IGameState
    {

        public event CreatedDelegate OnCreated;
        public event FinishStatDelegate  OnFinishStatEvent;
        public Room Room { get; set; }
        public GeneratedGameDto GeneratedGame { get; set; }
        public List<PlayerSummaryDto> PlayerSummaries { get; set; }
        public SerializableDictionary<string, List<PlayedGameRoundDto>> PlayedGameRound { get; set; } 
        public FinalRoomDto FinalRoom { get; set; }
        GameOnlineLoader _go;

        public System.Collections.Generic.List<string> Players { get; set; }

        public void InitPlayedGameRoundDto(SerializableDictionary<string, List<PlayedGameRoundDto>> lst) 
        {
            PlayedGameRound = lst;
          
        
        }
        public void AddPlayedGameRoundDto(PlayedGameRoundDto pgr) 
        {
            string pseudo = pgr.Player;

            if (PlayedGameRound == null) 
            {
                PlayedGameRound = new SerializableDictionary<string, List<PlayedGameRoundDto>>();  
            }

            if (!PlayedGameRound.ContainsKey(pseudo)) 
            {
                PlayedGameRound.Add(pseudo, new List<PlayedGameRoundDto>());   
            }

            PlayedGameRound[pseudo].Add(pgr);  

        
        }

        Guid MemoryCheckId;

        public GameState(Room r)
        {
            Room = r;
            Players = new System.Collections.Generic.List<string>();
            PlayerSummaries = new List<PlayerSummaryDto>(); 
            AddPlayer(Proxy.Instance.UserName);
            MemoryCheckId = MemoryCheck.Register(this, this.GetType().FullName);
        }
       
        public void Copy(IGameState g)
        {
            this.FinalRoom = g.FinalRoom;
            this.PlayedGameRound = g.PlayedGameRound;
            this.Players = g.Players;
            this.PlayerSummaries = g.PlayerSummaries;
            this.Room = g.Room;
            this.GeneratedGame = g.GeneratedGame; 
        }


        public void AddSummary(PlayerSummaryDto summary)
        {
            PlayerSummaryDto dto = PlayerSummaries.Find(p => p.Player == summary.Player);

            if (dto == null)
            {
                PlayerSummaries.Add(summary);
            }
            else
            {
                PlayerSummaries.Remove(dto);
                PlayerSummaries.Add(summary);
            }
        }


        public System.Collections.Generic.List<PlayedGameRoundDto> GetPlayerGame(string player)
        {
            return Room.GetPlayerGame(player);
        }


        public void AddPlayer(string player)
        {
            if (!Players.Contains(player))
            {
                Players.Add(player);
            }
        }

        public void RemovePlayer(string player)
        {
            if (Players.Contains(player))
            {
                Players.Remove(player);
            }
        }

        public void GenerateGame(bool stat= false)
        {
            if (_go != null) {
                _go.Dispose();
            }

            GeneratedGameDto gg = new GeneratedGameDto();
            gg.Config = Room.Configuration;
           
            _go = new GameOnlineLoader(gg);
            if (!stat)
            {
                _go.OnGameCreated += new GameOnlineLoader.OnGameCreatedEvent(go_OnGameCreated);
            }
            else
            {
                _go.OnFinishStat += new GameOnlineLoader.OnFinishGameStatEvent(go_OnFinishStat);
            }
            _go.GenerateLocalGame(stat);
        }

        void go_OnFinishStat(object s)
        {
            if (OnFinishStatEvent != null) 
            {
                OnFinishStatEvent(s); 
            }
        }

        void go_OnGameCreated(GeneratedGameDto game)
        {
            PlayerSummaries = new List<PlayerSummaryDto>(); 
            GeneratedGame = game; 
            MessageProxy.Proxy.SetGame(game);
            OnCreated(Room);
        }

        public GameRoundDto GetRound(int round)
        {
            if (round <= GeneratedGame.Rounds.Count)
            {
                return GeneratedGame.Rounds[round-1];
            }

            return null;
        }

        public PlayerSummaryDto GetPlayerSummary()
        {
            string pseudo = MessageProxy.Proxy.Session.Pseudo;
            PlayerSummaryDto dto = PlayerSummaries.Find(p => p.Player == pseudo);
            if (dto == null)
            {
                dto = new PlayerSummaryDto();
                dto.Player = MessageProxy.Proxy.Session.Pseudo;
                PlayerSummaries.Add(dto);
            }

            return dto;
        }

        public void Dispose()
        {
            Room = null;
            if (PlayerSummaries != null) PlayerSummaries.Clear();
            if (PlayedGameRound != null) PlayedGameRound.Clear();
            if (_go != null)
            {
                _go.Dispose();
            }
            _go = null;
            MemoryCheck.Unregister(MemoryCheckId);
        }
    }
}
